import requests
from requests.adapters import HTTPAdapter
from typing import Dict, Optional, Union
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class HttpClient:
    def __init__(self, timeout: int = 10, max_retries: int = 3, headers=None):
        self.headers = headers or {"User-Agent": "Mozilla/5.0"}
        self.session = requests.Session()
        self.timeout = timeout

        # 配置请求重试
        adapter = HTTPAdapter(
            max_retries=max_retries,
            pool_connections=100,
            pool_maxsize=100
        )
        self.session.mount('http://', adapter)
        self.session.mount('https://', adapter)

    def _log_request(self, method: str, url: str):
        """记录请求日志"""
        logger.info(f"🌐 [{method.upper()}] {url}")

    def _handle_response(self, response: requests.Response):
        """处理响应数据"""
        logger.info(f"✅ [{response.status_code}] {response.url}")
        try:
            data = response.json() if 'application/json' in response.headers.get('Content-Type', '') else response.text
        except ValueError:
            data = response.text

        return {
            "status": response.status_code,
            "headers": dict(response.headers),
            "data": data
        }

    def _request(
            self,
            method: str,
            url: str,
            params: Optional[Dict] = None,
            data: Optional[Dict] = None,
            json: Optional[Dict] = None,
            headers: Optional[Dict] = None,
    ) -> Dict[str, Union[bool, str, dict]]:
        """统一请求方法"""
        try:
            self._log_request(method, url)

            response = self.session.request(
                method=method,
                url=url,
                params=params,
                data=data,
                json=json,
                headers=headers,
                timeout=self.timeout
            )

            return self._handle_response(response)

        except requests.exceptions.RequestException as e:
            logger.error(f"❌ [ERROR] Request failed: {str(e)}")
            raise

    def get_client(
            self,
            url: str,
            params: Optional[Dict] = None,
    ) -> Dict:
        """GET请求"""
        return self._request("GET", url, params=params, headers=self.headers)

    def post_client(
            self,
            url: str,
            data: Optional[Dict] = None,
            json: Optional[Dict] = None,
    ) -> Dict:
        """POST请求"""
        return self._request("POST", url, data=data, json=json, headers=self.headers)